#include "client.h"
void clean(){
    int ch;
    while((ch = getchar()) != '\n' && ch != EOF);
}

int recv1(int sockfd, void *buf, int length){
    int total = 0;
    char *p = (char *)buf;
    while(total < length){
        ssize_t sret = recv(sockfd,p+total,length-total,0);
        total += sret;
    }
    return total;
}
char client_perfix[300]="/root/wangpan_project/wangpanv3/client";
void help() {
    printf("\n");
    printf(" ------------------------------------------\t\n");
    printf(" |        cd切换目录                      | \t\n");
    printf(" |        ls展示当前目录下的信息          | \t\n");
    printf(" |        pwd我是谁我在哪我在干什么       | \t\n");
    printf(" |        local_ls展示本地有哪些文件      | \t\n");
    printf(" |        puts上传文件                    | \t\n");
    printf(" |        gets下载文件                    | \t\n");
    printf(" |        remove删除网盘上的文件          | \t\n");
    printf(" |        mkdir在网盘上创建一个目录       | \t\n");
    printf(" |        rmdir删除一个非空目录           | \t\n");
    printf(" |        help展示指令菜单                | \t\n");
    printf(" |        history展示最近使用过的指令     | \t\n");
    printf(" ------------------------------------------ \t\n");
    printf(" ---------请输入您想执行的指令!------------ \t\n");
};


int main(int argc, char *argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");

    //连接成功
    char username[50];
    char password[50];
    int flag=0;//判断是否需要用户选择注册还是登录
    int user_choice;

    printf("网盘欢迎您！\n");
    while(1){
        if(flag==0){
            printf("选择注册(0)还是登录(1),请输入0或1：");
            scanf("%d",&user_choice);
            clean();
        }
        if(user_choice != 0 && user_choice != 1){
            printf("你的选择错误，请重新选择\n");
            fflush(stdout);
            continue;
        }
        printf("请输入用户名：");
        fflush(stdout);
        fgets(username, sizeof(username), stdin);
        username[strcspn(username, "\n")] = '\0';

        printf("请输入密码: ");
        fflush(stdout);
        get_password(password, sizeof(password));

        if(user_choice == 0){
            int  ret = register_user(sockfd,username,password);
            if(ret == 0){//注册成功
                flag=1;
                user_choice=1;//选择直接登录
                continue;
            }else if(ret==-1){//用户已存在
                flag=1;
                user_choice=1;//选择直接登录
                continue;
            }else if(ret==-2){//格式错误
                flag=0;//重新选择登录还是注册
                continue;
            }
        }else{
            int ret = log_in(sockfd,username,password);
            if(ret == 0){//登录成功
                break;
            }else if(ret==-1){
                flag=0;//重新选择注册还是登录
                continue;
            }else if(ret==-2){//密码错误
                flag=1;
                user_choice=1;//重新登录
                continue;
            }else if(ret==-3){//重新选择注册还是登录
                flag=0;
                continue;
            }
        }
    }

    char curr_path[1024];//当前目录
    snprintf(curr_path, sizeof(curr_path), "%s@localhost:~$ ", username);//用户根目录

    char buf[1024];//存放命令
    train_t cmds;

    help();
    while(1){
        bzero(buf, sizeof(buf));
        bzero(&cmds, sizeof(train_t));

        printf("%s",curr_path);//每次重新输入命令都显示当前路径
        scanf(" %[^\n]", buf);//获取键盘输入

        char *p=strtok(buf," ");//解析命令前半部分
        if(strcmp(p,"cd")==0){
            cmds.type=CMD_CD;
            p=strtok(NULL,"\0");
            if(p!=NULL){//cd后面有字符串
                strcpy(cmds.data, p);
                cmds.length=strlen(p);
                send(sockfd, &cmds, sizeof(cmds.type)+ sizeof(cmds.length)+ cmds.length, 0);

                bzero(&cmds, sizeof(train_t));
                recv1(sockfd,&cmds.type,sizeof(cmds.type));
                recv1(sockfd,&cmds.length,sizeof(cmds.length));
                recv1(sockfd,&cmds.data,cmds.length);

                if(cmds.type==SEND_TIP){//错误信息
                    printf("%s\n", cmds.data);
                }else if(cmds.type==SEND_URL){//cd成功进入目录
                    snprintf(curr_path, sizeof(curr_path), "%s@localhost:%s$ ", username, cmds.data);
                }
                continue;
            }else if(p==NULL){
                snprintf(curr_path, sizeof(curr_path), "%s@localhost:~$ ", username);//回到家目录
            }
            else{//指令错误
                printf("指令错误\n");
                continue;
            }
        }else if(strcmp(p,"ls")==0){
            cmds.type = CMD_LS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                /* printf("%d\n",cmds.length); */
                /* printf("%s\n",cmds.data); */
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            }else{
                cmds.length=0;//ls后面没有参数,发空data给服务端
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            }
            bzero(&cmds, sizeof(train_t));
            recv1(sockfd,&cmds.type,sizeof(cmds.type));
            recv1(sockfd,&cmds.length,sizeof(cmds.length));
            recv1(sockfd,&cmds.data,cmds.length);
            /* printf("\n"); */
            printf("%s\n", cmds.data);
            continue;

        }else if(strcmp(p,"pwd")==0){
            cmds.type=CMD_PWD;
            cmds.length=0;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                printf("指令错误\n");
                continue;
            }
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);

            bzero(&cmds, sizeof(train_t));
            recv1(sockfd,&cmds.type,sizeof(cmds.type));
            recv1(sockfd,&cmds.length,sizeof(cmds.length));
            recv1(sockfd,&cmds.data,cmds.length);

            /* printf("\n"); */
            printf("%s\n",cmds.data);
            continue;
        }else if(strcmp(p,"puts")==0){//上传
            cmds.type=CMD_PUTS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                printf("%s\n",p);
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
                client_putsfile(sockfd,cmds.data);
                continue;
            }else{//puts后面没有参数
                printf("指令错误\n");
                continue;
            }
        }else if(strcmp(p,"gets")==0){//下载
            cmds.type=CMD_GETS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
                client_getsfile(sockfd,cmds.data);
                continue;
            }else{//gets后面没有参数
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"remove")==0){
            cmds.type=CMD_REMOVE;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);

                bzero(&cmds, sizeof(train_t));
                recv1(sockfd,&cmds.type,sizeof(cmds.type));
                recv1(sockfd,&cmds.length,sizeof(cmds.length));
                recv1(sockfd,&cmds.data,cmds.length);

                printf("%s\n", cmds.data);
                continue;
            }else{//remove后面没有参数
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"mkdir")==0){
            cmds.type=CMD_MKDIR;
            p=strtok(NULL,"\0");
            if(p==NULL){
                printf("指令错误\n");
                continue;
            }
            cmds.length=strlen(p);
            strcpy(cmds.data, p);
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);

            bzero(&cmds, sizeof(train_t));
            recv1(sockfd,&cmds.type,sizeof(cmds.type));
            recv1(sockfd,&cmds.length,sizeof(cmds.length));
            recv1(sockfd,&cmds.data,cmds.length);

            printf("%s\n", cmds.data);
            continue;
        }else if(strcmp(p,"rmdir")==0){
            cmds.type=CMD_RMDIR;
            p=strtok(NULL,"\0");
            if(p==NULL){
                printf("指令错误\n");
                continue;
            }
            cmds.length=strlen(p);
            strcpy(cmds.data, p);
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);

            bzero(&cmds, sizeof(train_t));
            recv1(sockfd,&cmds.type,sizeof(cmds.type));
            recv1(sockfd,&cmds.length,sizeof(cmds.length));
            recv1(sockfd,&cmds.data,cmds.length);

            printf("%s\n", cmds.data);
            continue;
        }else if(strcmp(p,"help")==0){
            p=strtok(NULL,"\0");
            if(p!=NULL) printf("指令错误\n");
            help();
            continue;
        }else if(strcmp(p,"local_ls")==0){
            show_client_files(client_perfix); 
            continue;
        }

        else if(strcmp(p,"history")==0){
            cmds.type=CMD_HISTORY;
            cmds.length=0;
            p=strtok(NULL,"\0");
            if(p==NULL){
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);

                bzero(&cmds, sizeof(train_t));
                recv1(sockfd,&cmds.type,sizeof(cmds.type));
                recv1(sockfd,&cmds.length,sizeof(cmds.length));
                recv1(sockfd,&cmds.data,cmds.length);

                printf("%s\n",cmds.data);
                continue;
            }else{
                printf("指令错误\n");
                continue;
            }
        }
    }
    close(sockfd);
    return 0;
}

